//-----------------------Copyright © 2011 ForestryIS DevTeam. All rights reserved.------------------------
//
// <copyright file="Entity.Generic.cs" company="ForestryIS DevTeam.">
//     Copyright © 2011 ForestryIS DevTeam. All rights reserved.
// </copyright>
//
// <author>Sukhanov Maxim</author>
// 
//-----------------------Copyright © 2011 ForestryIS DevTeam. All rights reserved.------------------------

/* •——————————————————————————————————————————————SubVersion—————————————————————————————————————————————•
 * |
 * | Last Commit Info:
 * |    $Author: sukhanov.maxim $
 * |    $Revision: 2 $
 * |    $Date: 2011-03-19 21:56:11 +0000 (Sat, 19 Mar 2011) $
 * |    $URL: http://forestryis.googlecode.com/svn/trunk/ForestryIS.Model/Entities/Entity.Generic.cs $
 * |
 * •—————————————————————————————————————————————————————————————————————————————————————————————————————• */

/* •——————————————————————————————————————————————TODO List——————————————————————————————————————————————•
 * |                                                                                              
 * | <Nothing yet>                                                                                
 * |                                                                                              
 * •—————————————————————————————————————————————————————————————————————————————————————————————————————• */

namespace ForestryIS.Model.Entities
{
    using System;

    public abstract class Entity<TId>
    {
        public virtual TId Id { get; set; }

        protected virtual int Version { get; set; }

        public override bool Equals( object obj )
        {
            return Equals( obj as Entity<TId> );
        }

        private static bool IsTransient( Entity<TId> obj )
        {
            return obj != null && Equals( obj.Id, default( TId ) );
        }

        private Type GetUnproxiedType()
        {
            return GetType();
        }

        public virtual bool Equals( Entity<TId> other )
        {
            if ( other == null )
            {
                return false;
            }
            if ( ReferenceEquals( this, other ) )
            {
                return true;
            }
            if ( !IsTransient( this ) && !IsTransient( other ) && Equals( Id, other.Id ) )
            {
                var otherType = other.GetUnproxiedType();
                var thisType = GetUnproxiedType();
                return thisType.IsAssignableFrom( otherType ) || otherType.IsAssignableFrom( thisType );
            }
            return false;
        }

        public override int GetHashCode()
        {
            if ( Equals( Id, default( TId ) ) )
            {
                return base.GetHashCode();
            }
            return Id.GetHashCode();
        }
    }
}